/*
Copyright (C) 2022-2024 Inspur Corp.

SPDX-License-Identifier: Apache-2.0
*/
package controller

import (
	"encoding/json"
	"github.com/emicklei/go-restful"
	"icep/auth"
	"icep/bean/param"
	"icep/common/constant"
	"icep/common/crypto/gm"
	"icep/common/cryptoprovider"
	"icep/common/http"
	"strconv"
	"time"
	"unicode/utf8"
)

func (ic *IcepController) GetDataEvidencePage(req *restful.Request, resp *restful.Response) {
	userId := auth.GetCurrentUserId(req)

	strPageSize := req.QueryParameter("pageSize")
	strPageNo := req.QueryParameter("pageNum")
	evidenceName := req.QueryParameter("evidenceName")
	useEncrypt := req.QueryParameter("useEncrypt")
	startTime := req.QueryParameter("startTime")
	endTime := req.QueryParameter("endTime")

	if evidenceName != "" && utf8.RuneCountInString(evidenceName) > 50 {
		http.Failed(resp, "存证名称50字符以内")
		return
	}
	//查询时间符合判断
	var stime time.Time
	var err error
	if startTime != "" {
		stime, err = time.Parse(constant.TimeLayout, startTime)
		if err != nil {
			http.Failed(resp, "时间格式不符")
			return
		}
	}
	if endTime != "" {
		etime, err := time.Parse(constant.TimeLayout, endTime)
		if err != nil {
			http.Failed(resp, "时间格式不符")
			return
		} else if startTime != "" {
			if stime.After(etime) {
				http.Failed(resp, "开始时间大于结束时间")
				return
			}
		}
	}

	if useEncrypt != "" {
		if !(useEncrypt == "0" || useEncrypt == "1") {
			http.Failed(resp, "格式不符")
			return
		}
	}

	pageSize := 10
	if strPageSize != "" {
		pageSize, err = strconv.Atoi(strPageSize)
		if err != nil {
			http.Failed(resp, "页大小格式不符")
			return
		}
	}
	pageNo := 1
	if strPageNo != "" {
		pageNo, err = strconv.Atoi(strPageNo)
		if err != nil {
			http.Failed(resp, "页号格式不符")
			return
		}
	}

	page, err := ic.IcepService.GetDataEvidencePage(userId, evidenceName, useEncrypt, startTime, endTime, pageSize, pageNo)
	if err != nil {
		http.Failed(resp, "查询失败")
		return
	}
	http.OkWithData(resp, "查询成功", page)
}

func (ic *IcepController) GetDataEvidenceList(req *restful.Request, resp *restful.Response) {}

func (ic *IcepController) GetDataEvidenceInfo(req *restful.Request, resp *restful.Response) {
	evidenceId := req.QueryParameter("evidenceId")
	if evidenceId == "" {
		http.Failed(resp, "存证编号为空")
		return
	}
	userId := auth.GetCurrentUserId(req)

	dataEvidenceInfo, err := ic.IcepService.GetDataEvidenceInfo(userId, auth.GetCurrentTenantId(req), evidenceId)
	if err != nil {
		http.Failed(resp, "查询失败")
		return
	}
	http.OkWithData(resp, "查询成功", dataEvidenceInfo)
}

func (ic *IcepController) CreateDataEvidence(req *restful.Request, resp *restful.Response) {
	userId := auth.GetCurrentUserId(req)
	var dataEvidenceParam param.DataEvidenceParam
	if err := req.ReadEntity(&dataEvidenceParam); err != nil {
		http.Failed(resp, err)
		return
	}
	if dataEvidenceParam.EvidenceName == "" || utf8.RuneCountInString(dataEvidenceParam.EvidenceName) > 50 {
		http.Failed(resp, "存证名称为空或字符超过50")
		return
	}
	if dataEvidenceParam.UseEncrypt != "" {
		if !(dataEvidenceParam.UseEncrypt == "0" || dataEvidenceParam.UseEncrypt == "1") {
			http.Failed(resp, "格式不符")
			return
		}
	} else {
		http.Failed(resp, "是否加密存储为空")
		return
	}
	if dataEvidenceParam.EvidenceData != "" {
		jsonBool := json.Valid([]byte(dataEvidenceParam.EvidenceData))
		if !jsonBool {
			http.Failed(resp, "存证数据格式不符")
			return
		}
	} else {
		http.Failed(resp, "存证数据为空")
		return
	}

	err := ic.IcepService.CreateDataEvidence(userId, dataEvidenceParam)
	if err != nil {
		http.Failed(resp, "false")
		return
	}
	http.Ok(resp, "success")
}

func (ic *IcepController) CreateDataNokeyEvidence(req *restful.Request, resp *restful.Response) {
	userId := auth.GetCurrentUserId(req)
	var dataEvidenceParam param.DataEvidenceParam
	if err := req.ReadEntity(&dataEvidenceParam); err != nil {
		http.Failed(resp, err)
		return
	}
	if dataEvidenceParam.EvidenceName == "" || utf8.RuneCountInString(dataEvidenceParam.EvidenceName) > 50 {
		http.Failed(resp, "存证名称为空或字符超过50")
		return
	}
	if dataEvidenceParam.UseEncrypt != "" {
		if !(dataEvidenceParam.UseEncrypt == "0" || dataEvidenceParam.UseEncrypt == "1") {
			http.Failed(resp, "格式不符")
			return
		} else if dataEvidenceParam.UseEncrypt == "1" && dataEvidenceParam.EncryptedSecret == "" {
			http.Failed(resp, "加密存储下对称秘钥为空")
			return
		}
	} else {
		http.Failed(resp, "是否加密存储为空")
		return
	}
	if dataEvidenceParam.EvidenceData != "" && dataEvidenceParam.UseEncrypt == "0" {
		jsonBool := json.Valid([]byte(dataEvidenceParam.EvidenceData))
		if !jsonBool {
			http.Failed(resp, "存证数据格式不符")
			return
		}
	} else if dataEvidenceParam.EvidenceData == "" {
		http.Failed(resp, "存证数据为空")
		return
	}
	if dataEvidenceParam.Signature == "" {
		http.Failed(resp, "签名为空")
		return
	}

	err := ic.IcepService.CreateDataNokeyEvidence(userId, dataEvidenceParam)
	if err != nil {
		http.Failed(resp, "false")
		return
	}
	http.Ok(resp, "success")
}

func (ic *IcepController) DecryptDataEvidence(req *restful.Request, resp *restful.Response) {
	userId := auth.GetCurrentUserId(req)
	var dataEvidenceParam param.DataEvidenceParam
	if err := req.ReadEntity(&dataEvidenceParam); err != nil {
		http.Failed(resp, err)
		return
	}
	var userPrivateKey string
	if dataEvidenceParam.Password == "" {
		http.Failed(resp, "解密参数不符")
		return
	}
	user, result := ic.IcepService.GetUserByUserId(userId)
	if !result || !cryptoprovider.Get().Check(user.Password, dataEvidenceParam.Password) {
		http.Failed(resp, "该用户权限不足")
		return
	}
	userPrivateKey = user.PrvKey
	if userPrivateKey == "" {
		http.Failed(resp, "非秘钥托管类加密不支持")
		return
	}
	if dataEvidenceParam.EvidenceId == "" {
		http.Failed(resp, "存证编号为空")
		return
	}
	if dataEvidenceParam.EvidenceData == "" {
		http.Failed(resp, "加密数据为空")
		return
	}

	decryptedData, result := ic.IcepService.DecryptDataEvidence(userPrivateKey, dataEvidenceParam.EvidenceId, dataEvidenceParam.EvidenceData)
	if !result {
		http.Failed(resp, "解密失败")
		return
	}
	http.OkWithData(resp, "success", decryptedData)
}

func (ic *IcepController) CheckDataEvidence(req *restful.Request, resp *restful.Response) {
	var dataEvidenceParam param.DataEvidenceParam
	if err := req.ReadEntity(&dataEvidenceParam); err != nil {
		http.Failed(resp, err)
		return
	}
	if dataEvidenceParam.PubKey == "" {
		http.Failed(resp, "公钥为空")
		return
	}
	if dataEvidenceParam.Signature == "" {
		http.Failed(resp, "签名为空")
		return
	}
	if dataEvidenceParam.EvidenceData == "" {
		http.Failed(resp, "签名存证数据为空")
		return
	}
	result := gm.Verify(dataEvidenceParam.PubKey, []byte(dataEvidenceParam.EvidenceData), dataEvidenceParam.Signature)
	if result {
		http.Ok(resp, "验签成功")
	} else {
		http.Failed(resp, "验签失败")
	}
}
